// Copyright 2013 by Rod Moten
//
// This program is part of the Grambler project.
// 
// Grambler is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as 
// published by the Free Software Foundation, either version 3 of 
// the License, or (at your option) any later version.
//
// Grambler is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Grambler.  If not, see <http://www.gnu.org/licenses/>..
package edu.hendrix.grambler;

/**
 * Creators of actions should extend this class.
 * 
 * @author profmocs@gmail.com
 *
 */
public abstract class AbstractActionImpl implements Action {
	
	protected AbstractActionImpl() {
		
	}
	/**
	 * This method should be overridden if an action wants to recover from a previous error.
	 * The default behavior is to rethrow the exception.
	 * @param exception
	 * @param tree
	 * @return
	 * @throws ActionExecutionException 
	 */
	protected Object recoverFromError (Throwable throwable, Tree tree) throws Throwable {
		throw throwable;
	}

	
	/**
	 * Get the object produced from the action of the child with the given node.
	 * If the child node's action throw an exception, then the exception is thrown.
	 * @param tree
	 * @param name
	 * @return Returns the object produced from the action of the child with the given name.
	 * @throws Throwable
	 */
	protected Object getActionResultFromNamedChild (Tree tree, String name) throws Throwable {
		
		Tree node = tree.getNamedChild(name);
		if (node == null) {
			return null;
		}
		
		ActionResult actionResult =  node.getActionResult();
		if (actionResult == null) {
			return null;
		}
		if (actionResult.hasException()) {
			return recoverFromError(actionResult.getException(), tree);
		}
		return actionResult.getResult();
	}
	
	/**
	 * Get the object produced from the action of the n-th child.
	 * If the child node's action throw an exception, then the exception is thrown.
	 * @param tree
	 * @param n
	 * @return Returns the object produced from the action of the n-th child.
	 * @throws Throwable
	 */
	protected Object getActionResultFromdChild (Tree tree, int n) throws Throwable {
		
		Tree node = tree.getChild(n);
		if (node == null) {
			return null;
		}
		
		ActionResult actionResult =  node.getActionResult();
		if (actionResult == null) {
			return null;
		}
		if (actionResult.hasException()) {
			return recoverFromError(actionResult.getException(), tree);
		}
		return actionResult.getResult();
	}
}
